const oauth2orize = require('oauth2orize');
const passport = require('passport');
const crypto = require('crypto');
const { mysql } = require('../../db'); // 假设有一个模块负责数据库交互
const LocalStrategy = require('passport-local').Strategy;
const BearerStrategy = require('passport-http-bearer').Strategy;
const server = oauth2orize.createServer();

// 设置身份验证策略，例如使用用户名和密码
passport.use(new LocalStrategy(
    function (username, password, done) {
        mysql.users.finmysqlyUsername(username, function (err, user) {
            if (err) { return done(err); }
            if (!user) { return done(null, false); }
            if (!verifyPassword(user, password)) { return done(null, false); }
            return done(null, user);
        });
    }
));

passport.use(new BearerStrategy(
    function (accessToken, done) {
        mysql.accessTokens.find(accessToken, function (err, token) {
            if (err) { return done(err); }
            if (!token) { return done(null, false); }
            mysql.users.find(token.userID, function (err, user) {
                if (err) { return done(err); }
                if (!user) { return done(null, false); }
                done(null, user, { scope: token.scope });
            });
        });
    }
));

app.use(passport.initialize());

// 序列化客户端到会话
server.serializeClient(function (client, done) {
    return done(null, client.clientId);
});

server.deserializeClient(function (id, done) {
    mysql.clients.finmysqlyId(id, function (err, client) {
        if (err) { return done(err); }
        return done(null, client);
    });
});

// 注册授权码授予类型
server.grant(oauth2orize.grant.code({
    scopeSeparator: [' ']
}, function (client, redirectURI, user, ares, done) {
    const code = crypto.randomBytes(16).toString('hex');
    mysql.authorizationCodes.save(code, client.clientId, redirectURI, user.id, function (err) {
        done(err, err ? null : code);
    });
}));

// 交换授权码以令牌
server.exchange(oauth2orize.exchange.code(function (client, code, redirectURI, done) {
    mysql.authorizationCodes.find(code, function (err, authCode) {
        if (err || client.clientId !== authCode.clientId || redirectURI !== authCode.redirectURI) {
            return done(err);
        }
        const token = crypto.randomBytes(256).toString('base64');
        mysql.accessTokens.save(token, authCode.userId, authCode.clientId, function (err) {
            done(err, err ? null : token);
        });
    });
}));

app.post('/oauth/token',
    passport.authenticate(['local', 'oauth2-client-password'], { session: false }),
    server.token(),
    server.errorHandler()
);

app.get('/oauth/authorize',
    passport.authenticate('local', { session: false }),
    server.authorization(function (clientId, redirectURI, done) {
        mysql.clients.finmysqlyClientId(clientId, function (err, client) {
            if (err) { return done(err); }
            if (!client) { return done(null, false); }
            if (client.redirectURI !== redirectURI) { return done(null, false); }
            // 验证通过后执行授权
            return done(null, client, redirectURI);
        });
    }),
    function (req, res) {
        // 这里可以显示授权界面
        res.render('dialog', { transactionID: req.oauth2.transactionID });
    }
);

// 用户批准或拒绝授权
app.post('/oauth/authorize/decision',
    server.decision()
);

// OAuth 2.0 端点访问示例
app.get('/api/userinfo',
    passport.authenticate('bearer', { session: false }),
    function (req, res) {
        // req.user 包含授权的用户信息
        res.json({ user_id: req.user.id, name: req.user.username, scope: req.authInfo.scope })
    }
);

const port = process.env.PORT || 3000;
app.listen(port, () => {
    console.log(`OAuth 2.0 Authorization Server started on port ${port}`);
});
